<?php
// +----------------------------------------------------------------------
// | INPHP
// | Copyright (c) https://inphp.cc All rights reserved.
// | 该文件源码由INPHP官方提供，使用协议以INPHP官方公告为准。
// +----------------------------------------------------------------------
// | 退款
// +----------------------------------------------------------------------
namespace app\finance\onlinePay\alipay;

use app\finance\model\CashierModel;
use app\finance\onlinePay\IRefund;
use Inphp\Core\Object\Message;
use Inphp\Core\Util\Log;

class refund implements IRefund
{
    public function process(array $arg = []): Message
    {
        // TODO: Implement process() method.
//退款金额
        $amount = $arg["amount"] ?? 0;
        $amount = is_numeric($amount) && $amount > 0 ? $amount : 0;
        if ($amount <= 0) {
            return httpMessage("退款金额必须大于0");
        }
        //原订单付款总金额
        $payedAmount = $arg["payedAmount"] ?? 0;
        $payedAmount = is_numeric($payedAmount) && $payedAmount > 0 ? $payedAmount : 0;
        if ($payedAmount <= 0) {
            return httpMessage("原订单金额参数无效");
        }
        //退款单ID
        $refundId = $arg["refundId"] ?? 0;
        if (empty($refundId)) {
            return httpMessage("缺少退款单号");
        }
        //支付交易使用的订单号
        $payedTradeNo = $arg["payedTradeNo"] ?? null;
        if (empty($payedTradeNo)) {
            return httpMessage("缺少支付平台订单号");
        }
        //退款时，可能传入支付时使用的APP ID
        $appId = $arg["appId"] ?? null;
        //取配置
        $payments = CashierModel::payments();
        $config = $payments["alipay"] ?? null;
        if (empty($config)) {
            return httpMessage("缺少配置参数");
        }
        if (!$config["enable"]) {
            return httpMessage("该支付方式暂未开放");
        }
        $appList = $config["appList"] ?? [];
        if (empty($appList)) {
            return httpMessage("没有可用的支付应用");
        }
        $app = !empty($appId) ? ($appList[$appId] ?? reset($appList)) : reset($appList);
        $app = is_array($app) ? $app : [];
        if (empty($app)) {
            return httpMessage("未配置的支付应用");
        }
        $appId = $app["appId"] ?? $appId;
        if (empty($appId)) {
            return httpMessage("缺少支付应用ID");
        }
        //开发模式
        $dev = isset($app["dev"]) && $app["dev"] === true;
        //如果是开发模式，将把支付金额改为0.01元
        $amount = $dev ? 0.01 : $amount;
        //订单号前缀
        $outTradeNoPrefix = $app["outTradeNoPrefix"] ?? "";
        //生成单号
        $outRefundNo = $outTradeNoPrefix.$refundId;
        //构造
        $alipayParams = new \Yurun\PaySDK\AlipayApp\Params\PublicParams;
        $alipayParams->appID = $appId;
        $alipayParams->appPrivateKey = $app["privateKey"];
        $alipayParams->appPublicKey = $app["publicKey"];
        //
        $sdk = new \Yurun\PaySDK\AlipayApp\SDK($alipayParams);
        $sdkRequest = new \Yurun\PaySDK\AlipayApp\Params\Refund\Request;
        $sdkRequest->businessParams->trade_no = $payedTradeNo;
        $sdkRequest->businessParams->refund_amount = $amount;
        $sdkRequest->businessParams->out_request_no = "r".$outRefundNo;
        $sdkRequest->businessParams->refund_reason = $arg["reason"] ?? "标准退款";
        //
        $result = $sdk->execute($sdkRequest);
        $result = is_array($result) ? $result : null;
        if (empty($result)) {
            return httpMessage("退款失败，无响应数据");
        }
        Log::writeToEnd(RUNTIME."/logs/alipayRefund.txt", $result);
        $response = $result['alipay_trade_refund_response'] ?? [];
        $code = $response['code'] ?? 0;
        $msg = strtolower($response['msg'] ?? 'null');
        $success = $code == 10000 && $msg == "success";
        return httpMessage($success ? 0 : 1, $msg, [
            //实际退款金额
            "refundAmount"  => $response["refund_fee"],
            //接口响应数据，可保存备份
            "result"        => $response
        ]);
    }

    public function notify(?string $appId = null)
    {
        // TODO: Implement notify() method.
    }
}